package handler

import (
	"github.com/gin-gonic/gin"
	"github.com/honwee/awm/internal/api/dto"
	"github.com/honwee/awm/internal/service"
	"github.com/honwee/awm/pkg/logger"
	"go.uber.org/zap"
	"net/http"
)

type WorkflowRunHandler struct {
	workflowRunService *service.WorkflowRunService
	log                *zap.SugaredLogger
}

func NewWorkflowRunHandler(workflowRunService *service.WorkflowRunService) *WorkflowRunHandler {
	return &WorkflowRunHandler{
		workflowRunService: workflowRunService,
		log:                logger.Logger.Sugar(),
	}
}

// CreateWorkflowRun godoc
// @Summary 创建工作流运行记录
// @Description 创建新的工作流运行记录
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param Authorization header string true "Bearer {api_key}"
// @Param request body dto.CreateWorkflowRunRequest true "创建工作流运行记录请求"
// @Success 200 {object} dto.WorkflowRunResponse
// @Failure 400 {object} map[string]string
// @Failure 401 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs [post]
func (h *WorkflowRunHandler) CreateWorkflowRun(c *gin.Context) {
	var req dto.CreateWorkflowRunRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 从上下文获取user_id
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "user_id not found in context"})
		return
	}

	run := req.ToModel(userID.(string))
	if err := h.workflowRunService.CreateWorkflowRun(run); err != nil {
		h.log.Errorw("Failed to create workflow run",
			"workflow_run_id", req.WorkflowRunID,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunResponse{}
	response.FromModel(run)
	c.JSON(http.StatusOK, response)
}

// UpdateWorkflowRun godoc
// @Summary 更新工作流运行记录
// @Description 更新工作流运行记录的状态和完成时间
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Param workflow_run_id path string true "工作流运行ID"
// @Param Authorization header string true "Bearer {api_key}"
// @Param request body dto.UpdateWorkflowRunRequest true "更新工作流运行记录请求"
// @Success 200 {object} dto.WorkflowRunResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs/{workflow_run_id} [put]
func (h *WorkflowRunHandler) UpdateWorkflowRun(c *gin.Context) {
	workflowRunID := c.Param("workflow_run_id")
	if workflowRunID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow_run_id is required"})
		return
	}

	var req dto.UpdateWorkflowRunRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.workflowRunService.UpdateWorkflowRun(workflowRunID, req.Status, req.FinishedAt); err != nil {
		h.log.Errorw("Failed to update workflow run",
			"workflow_run_id", workflowRunID,
			"error", err)
		c.Error(err)
		return
	}

	run, err := h.workflowRunService.GetWorkflowRun(workflowRunID)
	if err != nil {
		h.log.Errorw("Failed to get workflow run after update",
			"workflow_run_id", workflowRunID,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunResponse{}
	response.FromModel(run)
	c.JSON(http.StatusOK, response)
}

// GetWorkflowRun godoc
// @Summary 获取工作流运行记录详情
// @Description 根据工作流运行ID获取运行记录详情
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Param workflow_run_id path string true "工作流运行ID"
// @Success 200 {object} dto.WorkflowRunResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs/{workflow_run_id} [get]
func (h *WorkflowRunHandler) GetWorkflowRun(c *gin.Context) {
	workflowRunID := c.Param("workflow_run_id")
	if workflowRunID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow_run_id is required"})
		return
	}

	run, err := h.workflowRunService.GetWorkflowRun(workflowRunID)
	if err != nil {
		h.log.Errorw("Failed to get workflow run",
			"workflow_run_id", workflowRunID,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunResponse{}
	response.FromModel(run)
	c.JSON(http.StatusOK, response)
}

// GetUserWorkflowRuns godoc
// @Summary 获取用户的工作流运行记录列表
// @Description 根据用户ID获取工作流运行记录列表
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer {api_key}"
// @Param user_id path string true "用户ID"
// @Param page query int false "页码（从1开始）" default(1) minimum(1)
// @Param page_size query int false "每页大小" default(10) minimum(1) maximum(100)
// @Success 200 {object} dto.WorkflowRunListResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs/user/{user_id} [get]
func (h *WorkflowRunHandler) GetUserWorkflowRuns(c *gin.Context) {
	userID := c.Param("user_id")
	if userID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "user_id is required"})
		return
	}

	var pagination dto.PaginationQuery
	if err := c.ShouldBindQuery(&pagination); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	runs, total, err := h.workflowRunService.GetUserWorkflowRuns(userID, pagination.GetOffset(), pagination.GetLimit())
	if err != nil {
		h.log.Errorw("Failed to get user workflow runs",
			"user_id", userID,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunListResponse{}
	response.FromModelList(runs, pagination.Page, pagination.PageSize, total)
	c.JSON(http.StatusOK, response)
}

// GetWorkflowRunsByStatus godoc
// @Summary 获取指定状态的工作流运行记录列表
// @Description 根据状态获取工作流运行记录列表
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Param status path string true "状态" Enums(running, succeeded, failed)
// @Param page query int false "页码（从1开始）" default(1) minimum(1)
// @Param page_size query int false "每页大小" default(10) minimum(1) maximum(100)
// @Success 200 {object} dto.WorkflowRunListResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs/status/{status} [get]
func (h *WorkflowRunHandler) GetWorkflowRunsByStatus(c *gin.Context) {
	status := c.Param("status")
	if status == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "status is required"})
		return
	}

	var pagination dto.PaginationQuery
	if err := c.ShouldBindQuery(&pagination); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	runs, total, err := h.workflowRunService.GetWorkflowRunsByStatus(status, pagination.GetOffset(), pagination.GetLimit())
	if err != nil {
		h.log.Errorw("Failed to get workflow runs by status",
			"status", status,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunListResponse{}
	response.FromModelList(runs, pagination.Page, pagination.PageSize, total)
	c.JSON(http.StatusOK, response)
}

// GetWorkflowRuns godoc
// @Summary 获取工作流的运行记录列表
// @Description 根据工作流ID获取运行记录列表
// @Tags 工作流运行记录
// @Accept json
// @Produce json
// @Param workflow_id path string true "工作流ID"
// @Param page query int false "页码（从1开始）" default(1) minimum(1)
// @Param page_size query int false "每页大小" default(10) minimum(1) maximum(100)
// @Success 200 {object} dto.WorkflowRunListResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /workflow-runs/workflow/{workflow_id} [get]
func (h *WorkflowRunHandler) GetWorkflowRuns(c *gin.Context) {
	workflowID := c.Param("workflow_id")
	if workflowID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow_id is required"})
		return
	}

	var pagination dto.PaginationQuery
	if err := c.ShouldBindQuery(&pagination); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	runs, total, err := h.workflowRunService.GetWorkflowRuns(workflowID, pagination.GetOffset(), pagination.GetLimit())
	if err != nil {
		h.log.Errorw("Failed to get workflow runs",
			"workflow_id", workflowID,
			"error", err)
		c.Error(err)
		return
	}

	response := &dto.WorkflowRunListResponse{}
	response.FromModelList(runs, pagination.Page, pagination.PageSize, total)
	c.JSON(http.StatusOK, response)
}
